package com.xiaouyudeguang.common.abstracts;


import com.xiaouyudeguang.common.annotations.ConsumerForEvent;
import com.xiaouyudeguang.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 行为日志领域事件消费者
 * </p>
 *
 * @author zhaog
 * @version v1.0
 * @since 2020/9/3
 */
public abstract class AbstractConsumerForEvent<E> {

    protected static final Logger log = LoggerFactory.getLogger(AbstractConsumerForEvent.class);

    protected final String KEY_PATTEN = this.getClass().getAnnotation(ConsumerForEvent.class).key();

    protected static final String KEY_PATTERN = "lock:%s:%s";

    @Autowired(required = false)
    protected StringRedisTemplate stringRedisTemplate;

    public void doValidate(String message, E event, String id) throws Exception {
        try {
            if (event == null) {
                log.error("event is null");
                return;
            }
            String key = String.format(KEY_PATTERN, KEY_PATTEN, id);
            if (StringUtils.isNotBlank(stringRedisTemplate.opsForValue().get(key))) {
                log.info("REJECTED. ID: {}", id);
                return;
            }
            log.debug("RECEIVED. ID: {}, message = {} ", id, message);
            long start = System.currentTimeMillis();
            stringRedisTemplate.opsForValue().set(key, String.valueOf(start), 10, TimeUnit.MINUTES);
            doProcess(message, event);
            log.debug("CONSUMED. ID: {}, cost: {}ms", id, System.currentTimeMillis() - start);
        } catch (Exception e) {
            log.info(e.getMessage(), e);
        }
    }

    public abstract void doProcess(String message, E event) throws Exception;
}
